package com.colis.quartz.common.extension;

import com.colis.quartz.common.base.BaseBean;
import com.colis.quartz.common.base.BaseType;
import com.colis.quartz.common.base.PageParam;
import com.colis.quartz.common.base.PageResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;

import javax.annotation.PostConstruct;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Optional;

import static com.colis.quartz.common.constant.BaseConst.TYPE_MAP;


/**
 * 描述：
 *
 * @author wlp
 * @version 1.0.0
 * @date 2021/10/17 0:16
 */
@SuppressWarnings("ALL")
public abstract class BaseJpaService<M extends BaseJpaRepository<T>, T extends BaseBean> {

    @Autowired
    protected M mapper;

    /**
     * <p> 方法描述: 获取所有数据</p>
     *
     * @return List<T>
     * @author wlp
     * @date 2021/10/17 0:20
     */
    public List<T> findAll() {
        return mapper.findAll();
    }

    /**
     * <p> 方法描述: 根据id获取数据 </p>
     *
     * @param id
     * @return T
     * @author wlp
     * @date 2021/10/17 0:20
     */
    public Optional<T> getOne(Long id) {
        return mapper.findById(id);
    }

    /**
     * <p> 方法描述: 保存并刷新值</p>
     *
     * @param bean
     * @return T
     * @author wlp
     * @date 2021/10/17 0:21
     */
    public T saveOrUpdate(T bean) {
        return mapper.saveAndFlush(bean);
    }

    /**
     * <p> 方法描述: 根据ID更新数据 </p>
     *
     * @param bean
     * @return T
     * @author wlp
     * @date 2021/12/10 12:00
     */
    public void update(T bean) {

    }

    /**
     * <p> 方法描述: 根据id删除数据 </p>
     *
     * @param id
     * @author wlp
     * @date 2021/10/17 0:24
     */
    public void deleteById(Long id) {
        mapper.deleteById(id);
    }

    /**
     * <p> 方法描述: 分页获取数据</p>
     *
     * @param param 分页参数
     * @return PageResult<T>
     * @author wlp
     * @date 2021/12/6 16:49
     */
    public <P extends PageParam> PageResult<T> pageList(P param) {
        Page<T> page = mapper.findAll(PageRequest.of(param.getPageIndex(), param.getPageSize()));
        return PageResult.start(page);
    }

    @PostConstruct
    private void init() {
        Type genType = getClass().getGenericSuperclass();
        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
        Class<M> mClass = (Class) params[0];
        Class<T> tClass = (Class) params[1];
        BaseType<T, M> baseType = new BaseType<>(tClass, mClass, this);
        TYPE_MAP.put(tClass.getSimpleName(), baseType);
    }
}
